#include <iostream>
#include <mutex>

// 饿汉模式
class Singleton
{
public:
    static Singleton &GetInstance()
    {
        return _sin;
    }
    Singleton(const Singleton &sin) = delete;
    Singleton &operator=(const Singleton &sin) = delete;

private:
    Singleton() {}
    static Singleton _sin;
};
Singleton Singleton::_sin;

// 懒汉模式
class Singleton2
{
public:
    static Singleton2 &GetInstance()
    {
        if (_sin == nullptr)
        {
            _mutex.lock();
            if (_sin == nullptr)
            {
                _sin = new Singleton2;
            }
            _mutex.unlock();
        }
        return *_sin;
    }
    Singleton2(const Singleton2 &sin) = delete;
    Singleton2 &operator=(const Singleton2 &sin) = delete;

private:
    Singleton2() {}
    static Singleton2 *_sin;
    static std::mutex _mutex;
};
Singleton2 *Singleton2::_sin;
std::mutex Singleton2::_mutex;

// 使用 std::call_once：C++11 引入了 std::call_once
// 它可以用来保证静态成员的初始化只执行一次，即使在多线程环境中。
#include <mutex>

class Singleton3
{
public:
    static Singleton3 &GetInstance()
    {
        std::call_once(_once, []()
                       { _sin = new Singleton3(); });
        return *_sin;
    }
    Singleton3(const Singleton3 &sin) = delete;
    Singleton3 &operator=(const Singleton3 &sin) = delete;

private:
    Singleton3() {}
    static Singleton3 *_sin;
    static std::once_flag _once;
};

Singleton3 *Singleton3::_sin = nullptr;
std::once_flag Singleton3::_once;

class Singleton4
{
public:
    static Singleton4 &getInstance()
    {
        static Singleton4 sins;
        return sins;
    }

private:
    Singleton4() {}
    Singleton4(const Singleton4 &) = delete;
    Singleton4 &operator=(const Singleton4 &) = delete;
};